package org.linlinjava.litemall.web.service;

import org.apache.commons.lang3.RandomStringUtils;
import org.linlinjava.litemall.core.payment.paypal.service.impl.GoodsPaypalServiceImpl;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.beans.Constants;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.dto.LitemallAccountBookFormDto;
import org.linlinjava.litemall.db.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import static org.linlinjava.litemall.db.beans.Constants.ORDER_MADE_STATUS_NEW;
import static org.linlinjava.litemall.db.beans.Constants.ORDER_STATUS_ONGOING;
import static org.linlinjava.litemall.web.util.WebResponseCode.*;
@Service
public class WebCloverPayService {
    @Autowired
    private LumiereCloverPayLogService lumiereCloverPayLogService;
    @Autowired
    private LitemallOrderService orderService;
    @Autowired
    private LitemallRefundService litemallRefundService;
    @Autowired
    private LitemallRefundGoodsService litemallRefundGoodsService;
    @Autowired
    private LitemallRefundTaxService litemallRefundTaxService;
    @Autowired
    private LitemallAccountBookService litemallAccountBookService;
    @Autowired
    private LitemallOrderGoodsService orderGoodsService;
    @Autowired
    private LitemallOrderTaxService litemallOrderTaxService;
    @Autowired
    private LumiereCloverRefundLogService lumiereCloverRefundLogService;
    @Autowired
    private GoodsPaypalServiceImpl paypalService;

    @Transactional(rollbackFor = Exception.class)
    public Object cloverPay(String externalId, String orderId,String paymentId, Integer userId,String cardNo,String cardType,Integer shopId) {

        LitemallOrder ord = orderService.findById(Integer.valueOf(externalId));

        if (ord == null) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        paypalService.presentPoint(ord.getId(),null);

        LitemallOrder order = new LitemallOrder();
        order.setId(Integer.valueOf(externalId));
        order.setPayTime(LocalDateTime.now());
        order.setUserId(userId);
        order.setOrderSource(Constants.ORDER_SOURCE_POS);
        order.setPayType(Constants.ORDER_PAY_TYPE_CLOVER);
        order.setMadeStatus(ORDER_MADE_STATUS_NEW);
        order.setOrderStatus(ORDER_STATUS_ONGOING);
        orderService.updateById(order);

        LumiereCloverPayLog log = new LumiereCloverPayLog();
        log.setExternalId(externalId);
        log.setOrderId(orderId);
        log.setCardNo(cardNo);
        log.setPaymentId(paymentId);
        log.setCardType(cardType);
        log.setAddTime(LocalDateTime.now());
        log.setUpdateTime(LocalDateTime.now());
        log.setDeleted(false);
        lumiereCloverPayLogService.add(log);

        //addAccountBook(shopId, order.getActualPrice(), "clover pay", 0, Constants.BOOK_SOURCE_TYPE_ORDER);

        return ResponseUtil.ok();
    }

    @Transactional(rollbackFor = Exception.class)
    public Object cloverRefund(String externalId, String orderId, String paymentId, Integer userId, Integer shopId) {
        LitemallOrder order = orderService.findById(Integer.valueOf(externalId));
        String outRefundId = orderId;
        if (null == order) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        Short orderStatus = order.getOrderStatus();
        if (!(Constants.ORDER_STATUS_ONGOING.equals(orderStatus))) {
            return ResponseUtil.fail(ORDER_INVALID_REFUND, "只有待制作、已取餐或已完成的订单才能退款");
        }

        //创建退款
        LitemallRefund refund = new LitemallRefund();
        refund.setOrderId(Integer.valueOf(externalId));
        refund.setOrderShopId(order.getShopId());
        refund.setRefundShopId(shopId);
        refund.setOrderSn(order.getOrderSn());
        refund.setRefundSn(generateRefundSn());
        refund.setUserId(order.getUserId());

        if (outRefundId != null && outRefundId != "") {
            refund.setOutRefundId(outRefundId);
        } else {
            refund.setOutRefundId(null);
        }
        refund.setDeviceNo(order.getDeviceNo());
        Byte payType = order.getPayType();
        refund.setRefundType(payType);
        refund.setRefundState(Constants.REFUND_STATUS_ONGOING);//退款中
        refund.setAddUserId(userId);
        litemallRefundService.add(refund);

        Integer refundId = refund.getId();
        //查询订单商品
        BigDecimal goodsPrice = BigDecimal.ZERO;
        BigDecimal taxPrice = BigDecimal.ZERO;

        //退款订单商品数据
        List<LitemallOrderGoods> ogs = orderGoodsService.queryByOid(Integer.valueOf(externalId));

        for (LitemallOrderGoods pair : ogs) {

            Integer orderGoodsId = pair.getId();

            pair.setRefundNumber(pair.getNumber());
            orderGoodsService.updateById(pair);

            //创建退款商品
            LitemallRefundGoods refundGoods = new LitemallRefundGoods();
            refundGoods.setRefundId(refundId);
            refundGoods.setOrderId(Integer.valueOf(externalId));
            refundGoods.setOrderGoodsId(orderGoodsId);
            refundGoods.setGoodsId(pair.getGoodsId());
            refundGoods.setNumber(pair.getNumber());
            refundGoods.setUnitPrice(pair.getDiscountPrice());
            BigDecimal refundGoodsPrice = pair.getDiscountPrice().multiply(new BigDecimal(pair.getNumber()));
            refundGoods.setGoodsPrice(refundGoodsPrice);
            litemallRefundGoodsService.add(refundGoods);
            Integer refundGoodsId = refundGoods.getId();

            //创建退款税费
            BigDecimal refundTaxPrice = BigDecimal.ZERO;
            List<LitemallOrderTax> orderTaxs = litemallOrderTaxService.queryByOrderIdAndOrderGoodsId(Integer.valueOf(externalId), orderGoodsId);
            if (!CollectionUtils.isEmpty(orderTaxs)) {
                for (LitemallOrderTax orderTax : orderTaxs) {
                    LitemallRefundTax refundTax = new LitemallRefundTax();
                    refundTax.setRefundId(refundId);
                    refundTax.setRefundGoodsId(refundGoodsId);
                    refundTax.setCode(orderTax.getCode());
                    BigDecimal value = orderTax.getValue();
                    refundTax.setValue(value);
                    //计算code为GST或其他的税费是多少
                    BigDecimal price = refundGoodsPrice.multiply(value).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
                    refundTax.setPrice(price);
                    litemallRefundTaxService.add(refundTax);

                    refundTaxPrice = refundTaxPrice.add(price);
                }
            }

            //修改退款商品的税费
            refundGoods.setTaxPrice(refundTaxPrice);
            refundGoods.setPrice(refundGoodsPrice.add(refundTaxPrice));
            litemallRefundGoodsService.update(refundGoods);

            goodsPrice = goodsPrice.add(refundGoodsPrice);
            taxPrice = taxPrice.add(refundTaxPrice);
        }
        //实际支付金额
        BigDecimal actualPrice = order.getActualPrice();

        addAccountBook(order.getShopId(), actualPrice, "clover refund", 1, Constants.BOOK_SOURCE_TYPE_REFUND);

        //更新退款金额
        refund.setGoodsPrice(goodsPrice);
        refund.setTaxPrice(taxPrice);
        refund.setPrice(actualPrice);
        refund.setActualPrice(actualPrice);
        litemallRefundService.update(refund);


        //待制作状态的订单全部退款，则将订单状态设置为完成
        order.setOrderStatus(Constants.ORDER_STATUS_FINISHED);
        order.setCompleteTime(LocalDateTime.now());
        order.setRefundStatus(Constants.ORDER_REFUND_STATUS_SUCCESS);

        //更新订单是否退款字段
        order.setIsRefund(true);
        orderService.updateById(order);


        //插入clover退款记录
        LumiereCloverRefundLog log = new LumiereCloverRefundLog();
        log.setExternalId(externalId);
        log.setOrderId(orderId);
        log.setPaymentId(paymentId);
        log.setAddTime(LocalDateTime.now());
        log.setUpdateTime(LocalDateTime.now());
        log.setDeleted(false);
        lumiereCloverRefundLogService.add(log);

        return ResponseUtil.ok(refundId);
    }

    private void addAccountBook(Integer shopId, BigDecimal actualPrice, String remark, Integer recordType, Integer sourceType) {
        LitemallAccountBookFormDto form = new LitemallAccountBookFormDto();
        form.setShopId(shopId);
        form.setRecordType(recordType);
        form.setRecordDate(LocalDateTime.now());
        form.setAmount(actualPrice);
        form.setRemark(remark);
        form.setSourceType(sourceType);
        litemallAccountBookService.create(shopId, form);
    }

    private String generateRefundSn() {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String now = df.format(LocalDateTime.now());
        return "T" + now + RandomStringUtils.randomAlphanumeric(4);
    }


}
